#include "UdpReceive.h"

UdpReceive::UdpReceive(QObject *parent):QObject(parent)
{
    //udp
    mUdpMultiRecCounter = 0;
    mUdpSocketAll=new QUdpSocket();
    isConnected = false;
    connect(this, &UdpReceive::SnRequestConnect, this,
            [this](QHostAddress udpAddr, int udpPort, QHostAddress multiAddr,
            QNetworkInterface multiInterface, bool isUseInterface)
    {
        if(mUdpSocketAll==nullptr)
            mUdpSocketAll=new QUdpSocket();
        if(isConnected)
            mUdpSocketAll->disconnectFromHost();
        else
        {
            mUdpSocketAll->bind(udpAddr, udpPort,
                                QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
           if(isUseInterface)
               mUdpSocketAll->joinMulticastGroup(multiAddr,
                                                  multiInterface);
           else
               mUdpSocketAll->joinMulticastGroup(multiAddr);

           isConnected = true;
           SnConnectSuccess();
        }
    });
    connect(mUdpSocketAll, &QUdpSocket::connected, this, [this]()
    {
        isConnected = true;
        SnConnectSuccess();
    });
    connect(mUdpSocketAll, &QUdpSocket::disconnected, this, [this]()
    {
        isConnected = false;
        SnDisconnect();
    });
    connect(mUdpSocketAll, &QUdpSocket::readyRead, this, [this](){
        while (mUdpSocketAll->hasPendingDatagrams())
        {
            QNetworkDatagram datagram = mUdpSocketAll->receiveDatagram();
            QByteArray t = datagram.data();
            mUdpRecArrayBuf += t;
            mUdpMultiRecCounter += t.size();

            uint8_t recType=0;
            while (mUdpRecArrayBuf.size()>=3) {
                if(mUdpRecArrayBuf.front()!='T')
                {
                    mUdpRecArrayBuf.remove(0, 1);
                    continue;
                }
                else if(mUdpRecArrayBuf.mid(0, 3)=="TMF")
                {
                    recType = 1;
                    break;
                }
                else if(mUdpRecArrayBuf.mid(0, 3)=="TMA")
                {
                    recType = 2;
                    break;
                }
                else if(mUdpRecArrayBuf.mid(0, 3)=="TMS")
                {
                    recType = 3;
                    break;
                }
                else
                    mUdpRecArrayBuf.remove(0, 1);
            }

            switch (recType) {
            case 1:
            {
                if(mUdpRecArrayBuf.size() < sizeof(S_AngleType))
                    return ;
                QByteArray t2 = mUdpRecArrayBuf.mid(0, sizeof(S_AngleType));
                mUdpRecArrayBuf.remove(0, sizeof (S_AngleType));

                S_AngleType tAngleType;
                memcpy(&tAngleType, t2.data(), sizeof (S_AngleType));

                SnSendAngleResult(tAngleType);
                break;
            }
            case 2:
            {
                if(mUdpRecArrayBuf.size() < sizeof(S_AngleSlowType))
                    return ;
                QByteArray t2 = mUdpRecArrayBuf.mid(0, sizeof(S_AngleSlowType));
                mUdpRecArrayBuf.remove(0, sizeof (S_AngleSlowType));

                S_AngleSlowType tAngleType;
                memcpy(&tAngleType, t2.data(), sizeof (S_AngleSlowType));

                SnSendSlowAngleResult(tAngleType);
                break;
            }
            case 3:
            {
                if(mUdpRecArrayBuf.size() < sizeof(S_AngleReportType))
                    return ;
                QByteArray t2 = mUdpRecArrayBuf.mid(0, sizeof(S_AngleReportType));
                mUdpRecArrayBuf.remove(0, sizeof (S_AngleReportType));

                S_AngleReportType tAngleType;
                memcpy(&tAngleType, t2.data(), sizeof (S_AngleReportType));

                SnSendRepoAngleResult(tAngleType);
                break;
            }
            default:
                break;
            }

        }
    });

    // timer
    QTimer *timer1 = new QTimer;
    QTimer::singleShot(2000, this, [timer1]{timer1->start(1000);});
    timer1->connect(timer1, &QTimer::timeout, this, [this]()
    {
        SnSendRecCount(mUdpMultiRecCounter);
        mUdpMultiRecCounter=0;
    });

}

UdpReceive::~UdpReceive()
{
    if(mUdpSocketAll)
        mUdpSocketAll->abort();
}
